package com.erp.erp_ui.Message.service;

import com.erp.enums.ModuleTypeEnum;
import com.erp.erp_entitys.Department.DepartmentEntity;
import com.erp.erp_entitys.Department.DepartmentExample;
import com.erp.erp_entitys.Message.*;
import com.erp.erp_entitys.Message.UserUnReadGroupTypeRes;
import com.erp.erp_entitys.User.UserEntity;
import com.erp.erp_entitys.User.UserEntityExample;
import com.erp.erp_entitys.warehouse.entity.AnnexEntity;
import com.erp.erp_entitys.warehouse.entity.TempAnnexEntity;
import com.erp.erp_servers.Message.IMessageService;
import com.erp.erp_servers.Message.IMessageUserDetailService;
import com.erp.erp_servers.User.IUserService;
import com.erp.erp_servers.warehouse.IAnnexService;
import com.erp.erp_servers.warehouse.ITempAnnexService;
import com.erp.erp_ui.Message.req.EditMessageReq;
import com.erp.erp_ui.Message.res.EditMessageRes;
import com.erp.erp_ui.Message.res.QueryMessageRes;
import com.erp.erp_ui.warehouse.enums.DataIsValidEnum;
import com.erp.erp_ui.warehouse.req.AnnexReq;
import com.erp.erp_ui.warehouse.vo.AnnexVo;
import com.erp.utils.DateUtils;
import com.erp.utils.R;
import com.erp.utils.ResultStatusEnum;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zjk
 * @version 1.0
 * @description
 * @date 2021-11-21 15:28
 */
@Service
public class MessageAllService {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MessageAllService.class);
    /**
     * 消息接口
     */
    private final IMessageService messageService;
    /**
     * 附件接口
     */
    private final IAnnexService annexService;
    /**
     * 临时附件接口
     */
    private final ITempAnnexService tempAnnexService;

    /**
     * 用户消息详情表接口
     */
    private final IMessageUserDetailService messageUserDetailService;

    /**
     * 用户接口
     */
    private final IUserService userService;

    public MessageAllService(IMessageService messageService, IAnnexService annexService, ITempAnnexService tempAnnexService, IMessageUserDetailService messageUserDetailService, IUserService userService) {
        this.messageService = messageService;
        this.annexService = annexService;
        this.tempAnnexService = tempAnnexService;
        this.messageUserDetailService = messageUserDetailService;
        this.userService = userService;
    }

    /**
     * 新增消息
     * @param messageReq
     */
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public R editMessage(EditMessageReq messageReq, String createName, String createCode) throws ParseException {
        //主表 详情表 新增修改
        Integer id = addOrUpdate(messageReq,createName,createCode);
        //第二步：附件新增、修改
        boolean flag = addAnnex(messageReq.getAnnexList(), id, messageReq.getPublisherName(),messageReq.getPublisherCode());
        if (!flag) {
            log.info("消息-批量新增附件异常");
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        //第三步：删除临时附件信息
        deleteTempAnnex(messageReq.getAnnexList());
        return R.build(ResultStatusEnum.SUCCESS);
    }

    /**
     * 新增，修改消息
     * @param messageReq
     * @param createName
     * @param createCode
     * @return
     */
    public Integer addOrUpdate(EditMessageReq messageReq, String createName, String createCode) throws ParseException {
        MessageEntity entity=new MessageEntity();
        BeanUtils.copyProperties(messageReq,entity);
        entity.setRemindTime(DateUtils.convertStringToDate(messageReq.getRemindTime(),DateUtils.DATE_TIME_PATTERN));
        entity.setCreateCode(createCode);
        entity.setCreateName(createName);
        entity.setCreateTime(new Date());

        if (entity.getId()!=null){
            //修改主信息
            messageService.updateByPrimaryKeySelective(entity);
            //删除原来的数据
            MessageUserDetailExample example=new MessageUserDetailExample();
            MessageUserDetailExample.Criteria criteria = example.createCriteria();
            criteria.andMessageIdEqualTo(entity.getId());
            messageUserDetailService.deleteByExample(example);
        }else {
            //新增主信息
            messageService.insertSelective(entity);
        }

        //新增用户消息详情
        insertUserDetail(entity);

        return entity.getId();
    }

    /**
     * 添加 用户消息详情
     * @param entity
     */
   public void insertUserDetail(MessageEntity entity){
        //用户消息详情
        String receiverCodeStr = entity.getReceiverCode();
        String[] receiverCodeArray = receiverCodeStr.split(",");

        for (int i = 0; i < receiverCodeArray.length; i++) {
            MessageUserDetail userDetail=new MessageUserDetail();
            userDetail.setMessageId(entity.getId());
            if (entity.getCreateCode().equals(receiverCodeArray[i])){
                userDetail.setReadStatus(1);
            }else {
                userDetail.setReadStatus(0);
            }

            userDetail.setReceiverCode(receiverCodeArray[i]);
            messageUserDetailService.insertSelective(userDetail);
        }
    }

    /**
     * 附件新增
     *
     * @param annexReqs  附件信息
     * @param parentId 父id
     * @param operator   操作人
     * @param operatorNo 操作人编码
     * @return 是否新增成功(true : 成功 false : 失败)
     */
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public boolean addAnnex(List<AnnexReq> annexReqs, Integer parentId, String operator, String operatorNo) {
        try {
            //没有附件,不新增
            if (CollectionUtils.isEmpty(annexReqs)) {
                return true;
            }
            //存在附件,新增附件信息
            List<AnnexEntity> list = new ArrayList<>();
            //获取旧的附件id集合
            List<Integer> oldIds = new ArrayList<>();
            for (AnnexReq annexReq : annexReqs) {
                if (null != annexReq.getNews()) {
                    //属于旧附件 只取id,不新增
                    oldIds.add(annexReq.getId());
                    continue;
                }
                AnnexEntity annex = new AnnexEntity();
                BeanUtils.copyProperties(annexReq, annex);
                //设置关联模块id
                annex.setModuleId(ModuleTypeEnum.MESSAGE_FILE.getId());
                //设置关联模块父id
                annex.setParentId(parentId);
                //设置上传时间
                annex.setUploadTime(DateUtils.convertStringToDate(annexReq.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
                //设置修改时间
                annex.setUpdateTime(new Date());
                //设置操作人
                annex.setOperator(operator);
                //设置操作人编码
                annex.setOperatorNo(operatorNo);
                //设置数据有效
                annex.setValid(1);

                list.add(annex);
            }
            if (oldIds.size() > 0) {
                //通过模块，父id获取修改附件信息
                AnnexEntity annex = new AnnexEntity();
                annex.setModuleId(ModuleTypeEnum.MESSAGE_FILE.getId());
                annex.setParentId(parentId);
                //获取上次附件信息
                List<AnnexEntity> annexList = annexService.queryAll(annex);
                if (!CollectionUtils.isEmpty(annexList)) {
                    //获取上次附件id集合
                    List<Integer> oldAnnexIds = annexList.stream().map(p -> p.getId()).collect(Collectors.toList());
                    //得到被删除的附件id
                    Collection collection = new ArrayList(oldAnnexIds);
                    collection.removeAll(oldIds);
                    if (collection.size() > 0) {
                        Iterator<Integer> it = collection.iterator();
                        while (it.hasNext()) {
                            int id = it.next();
                            AnnexEntity annexEntity = new AnnexEntity();
                            annexEntity.setId(id);
                            //将被删除的附件设为失效
                            annexEntity.setValid(DataIsValidEnum.INVALID.getId());

                            annexService.update(annexEntity);
                        }
                    }
                }
            }
            if (!CollectionUtils.isEmpty(list)) {
                //附件批量新增
                int res = annexService.batchInsert(list);
                if (res == list.size()) {
                    return true;
                }
            }
            return true;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
    /**
     * 批量处理临时附件信息，将临时附件设置为失效
     *
     * @param annexReqs
     */
    public void deleteTempAnnex(List<AnnexReq> annexReqs) {
        //没有附件
        if (CollectionUtils.isEmpty(annexReqs)) {
            return;
        }
        //存在附件
        for (AnnexReq annex : annexReqs) {
            if (null != annex.getNews()) {
                //旧附件,不用修改
                continue;
            }
            TempAnnexEntity tempAnnex = new TempAnnexEntity();
            //设置临时附件id
            tempAnnex.setId(annex.getId());
            //设置修改时间
            tempAnnex.setUpdateTime(new Date());
            //将附件设置为失效
            tempAnnex.setValid(0);
            tempAnnexService.update(tempAnnex);
        }

    }

    /**
     * 根据id查询消息
     */
    public EditMessageRes queryById(Integer id){
        MessageEntity messageEntity = messageService.selectByPrimaryKey(id);
        EditMessageRes res=new EditMessageRes();
        BeanUtils.copyProperties(messageEntity,res);
        res.setCreateTime(DateUtils.format(messageEntity.getCreateTime(),DateUtils.DATE_TIME_PATTERN));
        res.setRemindTime(DateUtils.format(messageEntity.getRemindTime(),DateUtils.DATE_TIME_PATTERN));
        List<AnnexVo> annexDetail = getAnnexDetail(id);
        res.setAnnexList(annexDetail);
        return res;
    }


    /**
     * 获取附件详情
     */
    private List<AnnexVo> getAnnexDetail(Integer id) {
        AnnexEntity annex = new AnnexEntity();
        //设置模块id
        annex.setModuleId(ModuleTypeEnum.MESSAGE_FILE.getId());
        //设置父id
        annex.setParentId(id);
        //设置数据有效
        annex.setValid(DataIsValidEnum.VALID.getId());
        //调用接口查询附件信息
        List<AnnexEntity> annexList = annexService.queryAll(annex);
        if (CollectionUtils.isEmpty(annexList)) {
            return null;
        }
        List<AnnexVo> annexVos = annexList.stream().map(p -> {
            AnnexVo annexVo = new AnnexVo();
            //赋值
            BeanUtils.copyProperties(p, annexVo);
            //上传时间转换
            annexVo.setUploadTime(DateUtils.format(p.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
            //设置附件为旧附件,用以区分修改时附件状态
            annexVo.setNews(0);

            return annexVo;
        }).collect(Collectors.toList());

        return annexVos;
    }

    /**
     * 根据消息类型，创建人 查询数据
     * @param type 消息类型
     * @param createCode 创建人编号
     * @return
     */
    public PageInfo queryMessageByParam(Integer type, String createCode){
        MessageExample example=new MessageExample();
        MessageExample.Criteria criteria = example.createCriteria();
        criteria.andCreateCodeEqualTo(createCode);
        criteria.andMessageTypeEqualTo(type);
        example.setOrderByClause("create_time desc");
        List<MessageEntity> messageEntities = messageService.selectByExample(example);

        List<QueryMessageRes> messageResList=new ArrayList<>();
        for (MessageEntity p:messageEntities){
            QueryMessageRes res =new QueryMessageRes();
            BeanUtils.copyProperties(p,res);
            res.setCreateTime(DateUtils.format(p.getCreateTime(),DateUtils.DATE_TIME_PATTERN));
            res.setRemindTime(DateUtils.format(p.getRemindTime(),DateUtils.DATE_TIME_PATTERN));
            messageResList.add(res);
        }

        PageInfo pageInfo=new PageInfo(messageEntities);
        pageInfo.setList(messageResList);
        return pageInfo;
    }

    /**
     * 主页 批量删除
     * @param ids
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void delMessageByIds(List<Integer> ids){
        //删除附件
        for (Integer p:ids){
            annexService.deleteAnnex(ModuleTypeEnum.MESSAGE_FILE.getId(),p);
        }

        //删除消息主信息
        MessageExample example=new MessageExample();
        MessageExample.Criteria criteria = example.createCriteria();
        criteria.andIdIn(ids);
        messageService.deleteByExample(example);

        //删除消息详情表
        MessageUserDetailExample detailExample=new MessageUserDetailExample();
        MessageUserDetailExample.Criteria detailCriteria = detailExample.createCriteria();
        detailCriteria.andMessageIdIn(ids);
        messageUserDetailService.deleteByExample(detailExample);
    }


    /**
     * 删除消息
     * 其他地方需要用到的删除
     * @return
     */
    public void delMessageByMessage(MessageExample example){

        List<MessageEntity> messageEntities = messageService.selectByExample(example);
        List<Integer> ids = messageEntities.stream().map(p -> p.getId()).collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(ids)){
            //删除消息主信息
            MessageExample messageExample=new MessageExample();
            MessageExample.Criteria messageExampleCriteria = messageExample.createCriteria();
            messageExampleCriteria.andIdIn(ids);
            messageService.deleteByExample(messageExample);

            //删除消息详情表
            MessageUserDetailExample detailExample=new MessageUserDetailExample();
            MessageUserDetailExample.Criteria detailCriteria = detailExample.createCriteria();
            detailCriteria.andMessageIdIn(ids);
            messageUserDetailService.deleteByExample(detailExample);
        }

    }
    /**
     * 获取当前用户未读消息数量
     * @param userCode
     * @return
     */
    public Integer getUserUnReadNumber(String userCode){
        List<QueryUerMessageRes> resList = messageService.selectUerMessageRes(userCode, null);
        Integer num=0;
        for (QueryUerMessageRes p:resList) {
            if (p.getReadStatus()==0){
                if (p.getRemindTime()!=null){
                    if (p.getRemindTime().compareTo(new Date())<=0){//提醒时间小于等于当前时间
                        ++num;
                    }
                }else{
                    ++num;
                }
            }
        }

        return num;
    }

    /**
     * 查询当前登录人 的未读消息，根据类型分类
     * @param userCode
     * @return
     */
    public UserUnReadGroupTypeRes queryUnReadByType(String userCode){
        UserUnReadGroupTypeRes res = messageUserDetailService.queryUnReadByType(userCode);
        return res;
    }

    /**
     * 根据消息类型，消息接收人 查询数据
     * @param type 消息类型
     * @param userCode 当前登录人
     * @return
     */
    public PageInfo selectUserMessageByPage(Integer type, String userCode){
        List<QueryUerMessageRes> resList = messageService.selectUerMessageRes(userCode, type);
        PageInfo pageInfo=new PageInfo(resList);
        return pageInfo;
    }

    /**
     * 接收人自己的消息 批量删除
     * @return
     */
    public void delUerMessage(List<Integer> ids, String userCode){
        MessageUserDetailExample example=new MessageUserDetailExample();
        MessageUserDetailExample.Criteria criteria = example.createCriteria();
        criteria.andReceiverCodeEqualTo(userCode);
        criteria.andIdIn(ids);
        messageUserDetailService.deleteByExample(example);
    }


    /**
     * 获取 财务部管理员(CWB01)
     */
    public List<String> getFinanceDeptAdmin(){
        UserEntityExample example=new UserEntityExample();
        UserEntityExample.Criteria criteria = example.createCriteria();
        criteria.andDepartmentCodeEqualTo("CWB01");
        criteria.andMsnEqualTo("是");
        List<UserEntity> userEntityList = userService.selectByExample(example);
        List<String> collect = userEntityList.stream().map(p -> p.getCode()).collect(Collectors.toList());
        return collect;
    }

    /**
     * 获取 营销部门的总监(YXZJ003)
     */
    public List<String> getMarketingDirector(){
        UserEntityExample example=new UserEntityExample();
        UserEntityExample.Criteria criteria = example.createCriteria();
        criteria.andRolesLike("%YXZJ003%");
        List<UserEntity> userEntityList = userService.selectByExample(example);
        List<String> collect = userEntityList.stream().map(p -> p.getCode()).collect(Collectors.toList());
        return collect;
    }
//    /**
//     * 获取 营销部门的总监(YXZJ003)的用户
//     * 运动营养品事业部，国内事业部 都有营销总监。
//     * 根据当前登录人的部门，判断部门路径中是否含有这两个部门的编号
//     * 根据不同的部门编号获取 角色是营销总监的人员
//     *      如果有 运动营养品事业部：则获取这个部门中角色是营销总监的人员
//     *      如果有 国内事业部：则获取这个部门中角色是营销总监的人员
//     */
//    public List<String> getMarketingDirector(UserEntity user){
//      DepartmentExample example=new DepartmentExample();
//      DepartmentExample.Criteria criteria = example.createCriteria();
//      criteria.andPathLike("%"+user.getDepartmentCode()+"%");
//      List<DepartmentEntity> departmentEntityList = departmentService.selectByExample(example);
//        for (DepartmentEntity p:departmentEntityList) {
//            if (p.getPath().contains("YDYYPSYB01")){//YDYYPSYB01 运动营养品事业部
//                UserEntityExample userExample=new UserEntityExample();
//                UserEntityExample.Criteria userCriteria = userExample.createCriteria();
//                userCriteria.andRolesLike("%YXZJ003%");
//                userCriteria.andDepartmentCodeEqualTo("YDYYPSYB01");
//                List<UserEntity> userList = userService.selectByExample(userExample);
//                List<String> collect = userList.stream().map(g -> g.getCode()).collect(Collectors.toList());
//                return collect;
//            }
//            if (p.getPath().contains("GNSYB")){//GNSYB 国内事业部
//                UserEntityExample userExample=new UserEntityExample();
//                UserEntityExample.Criteria userCriteria = userExample.createCriteria();
//                userCriteria.andRolesLike("%YXZJ003%");
//                userCriteria.andDepartmentCodeEqualTo("GNSYB");
//                List<UserEntity> userList = userService.selectByExample(userExample);
//                List<String> collect = userList.stream().map(g -> g.getCode()).collect(Collectors.toList());
//                return collect;
//            }
//        }
//        return null;
//    }
}
